//
//  Utilities.m
//  HKOCRuler
//
//  Created by lbxia on 2018/11/23.
//  Copyright © 2018年 lbx. All rights reserved.
//

#import "Utilities.h"
#import <ARKit/ARKit.h>
#import <SceneKit/SceneKit.h>


@implementation UIImage (HKRuler)

- (UIImage*)inverted
{
    CIImage *ciImage = self.CIImage;
    if (!ciImage) {
        return self;
    }
  
    if (@available(iOS 11.0, *)) {
        return  [[UIImage alloc]initWithCIImage:[ciImage imageByApplyingFilter:@"CIColorInvert"]];
    } else {
        // Fallback on earlier versions
        return self;
    }
}
@end


@implementation WorldPostion
@end


@implementation Utilities

+ (CGFloat)distanceFromPos:(SCNVector3)from to:(SCNVector3)to
{
    SCNVector3 distance = SCNVector3Make(from.x - to.x, from.y - to.y, from.z - to.z);
    
    return sqrtf(powf(distance.x, 2)+powf(distance.y, 2)+powf(distance.z, 2));
    
}

+ (SCNPlane*)createPlaneWithSize:(CGSize)size contents:(id)contents
{
    SCNPlane *plane = [SCNPlane planeWithWidth:size.width height:size.height];
    plane.materials = @[ [SCNMaterial materialWithDiffuse:contents respondsToLighting:YES] ];
    return plane;
}

+ (SCNNode*)createAxesNodeWithQuiverLength:(CGFloat)quiverLength quiverThickness:(CGFloat)quiverThickness
{
    quiverThickness = (quiverLength / 50.0) * quiverThickness;
    CGFloat chamferRadius = quiverThickness / 2.0;
    
    SCNBox *xQuiverBox = [SCNBox boxWithWidth:quiverLength height:quiverThickness length:quiverThickness chamferRadius:chamferRadius];
    xQuiverBox.materials = @[ [SCNMaterial materialWithDiffuse:[UIColor redColor] respondsToLighting:NO] ];
    SCNNode *xQuiverNode = [SCNNode nodeWithGeometry:xQuiverBox];
    xQuiverNode.position = SCNVector3Make(quiverLength / 2.0, 0.0, 0.0);
    
    
    SCNBox *yQuiverBox = [SCNBox boxWithWidth:quiverThickness height:quiverLength length:quiverThickness chamferRadius:chamferRadius];
    yQuiverBox.materials = @[ [SCNMaterial materialWithDiffuse:[UIColor greenColor] respondsToLighting:NO] ];
    SCNNode *yQuiverNode = [SCNNode nodeWithGeometry:yQuiverBox];
    yQuiverNode.position = SCNVector3Make( 0.0,quiverLength / 2.0,0.0);
    
    
    SCNBox *zQuiverBox = [SCNBox boxWithWidth:quiverThickness height:quiverThickness length:quiverLength chamferRadius:chamferRadius];
    zQuiverBox.materials = @[ [SCNMaterial materialWithDiffuse:[UIColor blueColor] respondsToLighting:NO] ];
    SCNNode *zQuiverNode = [SCNNode nodeWithGeometry:zQuiverBox];
    zQuiverNode.position = SCNVector3Make( 0.0,0.0,quiverLength / 2.0);
    
    SCNNode *quiverNode = [[SCNNode alloc]init];
    [quiverNode addChildNode:xQuiverNode];
    [quiverNode addChildNode:yQuiverNode];
    [quiverNode addChildNode:zQuiverNode];
    quiverNode.name = @"Axes";
    
    
    return quiverNode;
}


#pragma mark- SCNVector3常见处理
+ (SCNVector3)positionFromTransform:(matrix_float4x4)transform
{
    return   SCNVector3Make(transform.columns[3].x, transform.columns[3].y, transform.columns[3].z);
}


+ (CGFloat)SCNVector3Length:(SCNVector3)s
{
    return sqrtf(s.x * s.x + s.y * s.y + s.z * s.z);
}

//left - right 减号
+ (SCNVector3)SCNVector3Sub:(SCNVector3)left right:(SCNVector3)right
{
    return SCNVector3Make(left.x - right.x, left.y - right.y, left.z - right.z);
}

//left + right 加号
+ (SCNVector3)SCNVector3Add:(SCNVector3)left right:(SCNVector3)right
{
    return SCNVector3Make(left.x + right.x, left.y + right.y, left.z + right.z);
}


//left * right 乘号
+ (SCNVector3)SCNVector3Product:(SCNVector3)left right:(CGFloat)right
{
    return SCNVector3Make(left.x * right, left.y * right, left.z * right);
}

//left cross right
+ (SCNVector3)SCNVector3Cross:(SCNVector3)left right:(SCNVector3)vec
{
    return SCNVector3Make(left.y * vec.z - left.z * vec.y, left.z * vec.x - left.x * vec.z, left.x * vec.y - left.y * vec.x);
}

+ (CGFloat)dot:(SCNVector3)left vec: (SCNVector3)vec
{
    return (left.x * vec.x) + (left.y * vec.y) + (left.z * vec.z);

}



//left/right 除号
+ (SCNVector3)SCNVector3DiV:(SCNVector3)left right:(CGFloat)right
{
    return SCNVector3Make(left.x / right, left.y / right, left.z / right);
}

//归化
+ (SCNVector3)SCNVector3Normalized:(SCNVector3)s
{
    CGFloat length = [self SCNVector3Length:s];
    if ( length == 0) {
        return s;
    }
    
    return [self SCNVector3DiV:s right:length];
}

+ (SCNVector3)SCNVector3Average:(NSArray<SCNVector3OBJ*>*)list
{
    SCNVector3 avergage = SCNVector3Zero;
    for (int i = 0; i < list.count; i++) {
        
        avergage.x += list[i].s.x;
        avergage.y += list[i].s.y;
        avergage.z += list[i].s.z;
    }
    
    avergage.x /= list.count;
    avergage.y /= list.count;
    avergage.z /= list.count;
    
    return avergage;
}

+ (SCNVector3OBJ*) rayIntersectionWithHorizontalPlane:(SCNVector3)rayOrigin
                                            direction:(SCNVector3)direction
                                               planeY:(CGFloat)planeY
{
    direction = [self SCNVector3Normalized:direction];
    
    if (direction.y == 0.0) {
        if (rayOrigin.y == planeY) {
          
            return [SCNVector3OBJ objectWith:rayOrigin];
            
        }else{
            return nil;
        }
    }
    
    CGFloat dist = (planeY - rayOrigin.y) / direction.y;
    
    if (dist < 0) {
        return nil;
    }
    
    SCNVector3 s = [self SCNVector3Add:rayOrigin right:[self SCNVector3Product:direction right:dist]];
    
    return [SCNVector3OBJ objectWith:s];;
}


@end


//包装SCNVector3
@implementation SCNVector3OBJ


+ (SCNVector3OBJ*)objectWith:(SCNVector3)s
{
    return [[SCNVector3OBJ alloc]initWithV3:s];
}

- (instancetype)initWithV3:(SCNVector3)s
{
    if (self = [super init]) {
        
        self.s = s;
    }
    return self;
}

- (CGFloat)x{
    return _s.x;
}

- (CGFloat)y{
    return _s.y;
}

- (CGFloat)z{
    return _s.z;
}

- (void)setX:(CGFloat)x{
    _s.x = x;
}

- (void)setY:(CGFloat)y{
    _s.y = y;
}

- (void)setZ:(CGFloat)z{
    _s.z = z;
}

@end


@implementation SCNMaterial(HKRuler)

+ (SCNMaterial*)materialWithDiffuse:(id)diffuse respondsToLighting:(BOOL)respondsToLighting
{
    SCNMaterial *material = [[SCNMaterial alloc]init];
    material.diffuse.contents = diffuse;
    material.doubleSided = YES;
    if (respondsToLighting) {
        material.locksAmbientWithDiffuse = YES;
    }else{
        material.ambient.contents = [UIColor blackColor];
        material.lightingModelName = SCNLightingModelConstant;
        material.emission.contents = diffuse;
    }
    
    return material;
}


@end

